#! /usr/bin/perl -w
#
# This file is part of Logtrack-ng.
#
# Logtrack is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Logtrack is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Logtrack; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

require 5.004;
use strict;
no strict 'refs';
no strict 'subs';
use FindBin;
$ENV{PWD} = $FindBin::Bin;
use lib "$FindBin::Bin/modules";

use Logtrack;
use Data::Dumper;

use POSIX qw(locale_h);
use POSIX;
setlocale(LC_TIME, 'POSIX');

use constant TRUE => 1;
use constant FALSE => 0;

my $sigset = POSIX::SigSet->new();
my $action = POSIX::SigAction->new('sig_handler',$sigset, &POSIX::SA_NODEFER);
POSIX::sigaction(&POSIX::SIGHUP, $action);
POSIX::sigaction(&POSIX::SIGTERM, $action);

sub sig_handler;
sub daemon_init;

	#-----MAIN_PROGRAM-------------
	our $logtrack = new Logtrack;
	if($logtrack->{data}{nodaemon} eq '') {
		daemon_init();
		open(STDIN,  '+>/dev/null');
		
		#Redirect program output to standart output or /dev/null
		if($logtrack->{debug}->{level}) {
			open(STDOUT, "&STDOUT");
		}
		else {
			open(STDOUT,  '+>/dev/null');
		}
		open(STDERR, "&STDERR");
	}

	$logtrack->online_analysis();

=item
Funkce spustena jako reakce na prichozi signal. Nejprve uzavre databazi, 
deskriptory a nakonec sockety. Nasledne ukonci program nebo ho restartuje
v zavislosti na prichozim signalu.

Function is executed as reaction to incoming signal. First, it close 
DB connection, descriptors and sockets. Furthermore it terminates itself 
or restart (that depends on incoming signal).
=cut

sub sig_handler {
	my $signame = shift;
	$logtrack->errstrln('Signal SIG'.$signame .' called');
	my $ref_db = $logtrack->{dbi}->get_db();
	$$ref_db->rollback;
	
	foreach my $file (@{$logtrack->{files}}) {
		next if($file eq '');
		$file->{fd}->close;
	}

	foreach my $socket (@{$logtrack->{sockets}}) {
		shutdown($socket,2);
	}

	$$ref_db->disconnect or $logtrack->errstr($$ref_db->errstr);
	if ($signame eq 'HUP') {
 		exec("$ENV{PWD}/logtrack-ng @{$logtrack->{data}{args}}");
	}
 	$logtrack = undef;
	exit(0);
}

=item
Function calls fork.Parent process before it's termination checks whether
it is possible to write child PID to /var/run, otherwise it sends SIGTERM to
child process and show error message.

If everything goes smoothly, child process calls setsid for being standalone
and continue in program

Funkce zavola fork a rodicovsky proces pred svym ukoncenim overi, zda jde
zapsat PID synovskeho procesu do /var/run/, pokud ne - zasle signal SIGTERM
synovskemu procesu a vypise hlasku.

Pokud je vse v poradku, synovsky proces zavola setsid pro odpoutani se 
od rodice a pokracuje dale v programu.
=cut

sub daemon_init {
	my $ref_db = $logtrack->{dbi}->get_db();
	$logtrack->{db} = $ref_db;
	$$ref_db->disconnect;
	
	my $pid = fork;
	exit 2 if not defined $pid;

	if($pid) {
		sleep 1;
		if(system ("echo \"$pid\" > /var/run/logtrack.pid") != 0) {
			kill 15, $pid;
			print STDERR 'Can\'t write to do /var/run !'."\n";
		}
		exit(0);
	}
	else {
		setsid();
		chdir '/' or die $!;
		umask 0;
	}
}

